package top.aigoo.project01.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import top.aigoo.project01.entity.Shop;
import top.aigoo.project01.entity.dto.ImageHolder;
import top.aigoo.project01.entity.dto.ShopExecution;
import top.aigoo.project01.enums.ShopStateEnum;
import top.aigoo.project01.exceptions.ShopOperationException;
import top.aigoo.project01.mapper.ShopMapper;
import top.aigoo.project01.service.ShopService;
import top.aigoo.project01.utils.ImageUtil;
import top.aigoo.project01.utils.PageCalculator;
import top.aigoo.project01.utils.PathUtil;

import java.io.File;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

/**
 * @Description: 商店 service
 * @Author: Mr.OYSHUO.欧阳大叔  mail:1642302522@qq.com
 * @Version 1.0.0
 * @Date: 2021/8/9 0:27
 */

@Service
public class ShopServiceImpl implements ShopService {

    private ShopMapper shopMapper;

    @Autowired
    public ShopServiceImpl(ShopMapper shopMapper) {
        this.shopMapper = shopMapper;
    }

    /**
     * 根据shopCondition分页返回响应店铺列表
     * @param shopCondition 商铺查询条件
     * @param pageIndex 当前页面
     * @param pageSize  每页内容大小
     * @return 店铺列表
     */
    @Override
    public ShopExecution getShopList(Shop shopCondition, int pageIndex, int pageSize) {

        int rowIndex = PageCalculator.calculateRowIndex(pageIndex, pageSize);

        List<Shop> shopList = shopMapper.queryShopList(shopCondition, rowIndex, pageSize);
        // 获取总数
        int count = shopMapper.queryShopCount(shopCondition);

        ShopExecution se = new ShopExecution();

        if (shopList != null) {
            se.setShopList(shopList);
            se.setCount(count);
        } else {
            se.setState(ShopStateEnum.INNER_ERROR.getState());
        }
        return se;
    }

    /**
     * 通过shopId查询店铺信息
     *
     * @param shopId 店铺id
     * @return 指定店铺信息
     */
    @Override
    public Shop getByShopId(long shopId) {
        return shopMapper.queryByShopId(shopId);
    }

    /**
     * 添加店铺
     * 使用注解控制事务方法的优点：
     * 1.开发团队达成一致约定，明确标注事务方法的编程风格
     * 2.保证事务方法的执行时间尽可能短，不要穿插其他网络操作，RPC/HTTP请求或者剥离到事务方法外部
     * 3.不是所有的方法都需要事务，如只有一条修改操作，只读操作不需要事务控制
     *
     * @param shop     店铺信息
     * @param thumbnail  店铺图片
     * @return
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ShopExecution addShop(Shop shop, ImageHolder thumbnail)
            throws RuntimeException {
        //1 检查参数合法性 空值判断 检查传递的shop 是否包含一些必须值
        if (shop == null) {
            return new ShopExecution(ShopStateEnum.NUll_ERROR);
        }
        //2.正式店铺注册逻辑实现
        try {
            //1. 初始化数据,给店铺信息初始值
            shop.setEnableStatus(0);
            shop.setCreateTime(new Date());
            shop.setUpdateTime(new Date());
            //2.添加店铺信息到数据库
            int effectedNum = shopMapper.insertShop(shop);
            //3. 获取id判断进行下一次操作
            if (effectedNum <= 0) {
                throw new RuntimeException("店铺创建失败");
            } else {
                try {
                    //4. 判断图片是否为空,不为空就添加图片
                    if (thumbnail.getImage() != null) {
                        //5.存储图片，并将更新后的图片地址更新到shop的图片地址中
                        addShopImg(shop, thumbnail);
                        //6.更新店铺的图片地址
                        effectedNum = shopMapper.updateShop(shop);
                        if (effectedNum <= 0) {//更新失败
                            throw new RuntimeException("创建图片地址失败!");
                        }
                    }
                } catch (Exception e) {
                    throw new RuntimeException("addShopImg error:" + e.getMessage());
                }
            }
        } catch (Exception e) {
            throw new RuntimeException("addShop error:" + e.getMessage());
        }
        return new ShopExecution(ShopStateEnum.CHECK, shop);
    }

    /**
     * 更新店铺信息
     *
     * @param shop               areaId  shopAddr  phone shopDesc
     * @param thumbnail 商铺图片
=     * @return
     * @throws RuntimeException
     */
    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public ShopExecution modifyShop(Shop shop, ImageHolder thumbnail)
            throws RuntimeException {
        if (shop == null || shop.getShopId() == null) {
            return new ShopExecution(ShopStateEnum.NULL_SHOPID);
        } else {
            // 1.判断是否需要处理图片
            try {
                if (thumbnail.getImage() != null && thumbnail.getImageName() != null && !"".equals(thumbnail.getImageName())) {
                    Shop tempShop = shopMapper.queryByShopId(shop.getShopId());
                    if (tempShop.getShopImg() != null) {
                        ImageUtil.deleteFileOrPath(tempShop.getShopImg()); //原来商铺有图片，我们先把原来的图片删除掉
                    }
                    addShopImg(shop, thumbnail);
                }
                // 2.更新店铺信息
                shop.setUpdateTime(new Date());
                int effectedNum = shopMapper.updateShop(shop);
                if (effectedNum <= 0) {
                    return new ShopExecution(ShopStateEnum.INNER_ERROR);
                } else {// 创建成功
                    shop = shopMapper.queryByShopId(shop.getShopId());
                    return new ShopExecution(ShopStateEnum.SUCCESS, shop);
                }
            } catch (Exception e) {
                throw new RuntimeException("modifyShop error: " + e.getMessage());
            }
        }
    }

    /**
     * 更新图片
     *
     * @param shop    商店
     * @param thumbnail 图片
     */
    private void addShopImg(Shop shop, ImageHolder thumbnail) {
        // 1.获取shop图片目录的相对路径 /upload/images/item/shop/12/
        String dest = PathUtil.getShopImagePath(shop.getShopId());
        // 2.存储图片并返回url
        String shopImgAddr = ImageUtil.generateThumbnail(thumbnail, dest);
        //更新图片地址
        shop.setShopImg(shopImgAddr);
    }
}
